﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace DarkBone
{
    public class Database
    {
        public Database() {}
        ~Database() {}

/*
         How to search for ptr to Database
         search for ##sight## with Cheatengine when in singleplayer lobby
0696CB18  23 23 73 69 67 68 74 23 23 00 00 00 00 00 00 00  ##sight##.......

         * search for ptr to name of unit
         * near that ptr (- 0x0C there is lenght of the modelname), on this address is (lenght > 7)?ptrtochar:nameitself
057E21B4  09_00_00_00 87 00 00 00 18_CB_96_06 00 00 00 00  ....‡...Ë–.... //name length, ptr to name (or name itself)
         
         * search for ptr to modellength, when you find it, +0x0C is modelid
         * sub that ptr to model by 0x04
0696CB00  52 AF 20 77 B4_21_7E_05 C1 33 5C 35 10 80 91 05  R¯ w´!~Á3\5€‘ //ptr to model name struct
0696CB10  00_00_00_00 1B 00 00 00 23 23 73 69 67 68 74 23  .......##sight# //model id
         
         * search that ptr to that address
         * you should find array of ptrs to models
35A16BE0  10 AB 5F 26 00 00 00 00 00 00 00 00 0B 16 00 00  «_&..........
35A16BF0  00_CB_96_06 B0 74 9E 06 80 A0 A0 06 98 8E A9 06  .Ë–°tž€  ˜Ž© //first unit
35A16C00  B8 61 AA 06 80 6F A8 06 20 70 A8 06 08 13 AA 06  ¸aª€o¨ p¨ª
         
         * seach for ptr to the first unit (##sight##)
067FB66C  F0_6B_A1_35 00 00 00 00 00 01 00 00 00 01 00 00  ðk¡5..........
         
         * voila...
         
         
	cli::array<Byte>^ model = gcnew cli::array<Byte>(0x1C);
	System::Text::Encoding^ ascii = System::Text::Encoding::ASCII;
	cli::array<Byte>^ zptr = gcnew cli::array<Byte>(0x04);
	ReadMemory(IntPtr((Int32)this->m_bVision->GetPtrToUnitDatabase()), zptr);
	Int32 databaseptr = BitConverter::ToInt32(zptr, 0x00) + 0xD8;
	ReadMemory(IntPtr(databaseptr), zptr);
	databaseptr = BitConverter::ToInt32(zptr, 0x00) + 0x90;
	ReadMemory(IntPtr(databaseptr), zptr);
	databaseptr = BitConverter::ToInt32(zptr, 0x00);
          
*/
        

public static void GetUnitInfo() {
	MemoryReader r = new MemoryReader();
   int id = 0;
	if (!r.GetProcess("SC2", ref id)) {
		throw new Exception("ERROR: SC2 not found!");
	}
    //Int32 pDatabase = 0x067FB66C;
    Int32 pFirstUnit = 0x2549F32C;
    //r.ReadMemoryInt32((IntPtr)(pDatabase), ref pFirstUnit);
    String s = "public static String[] units_table = {" + Environment.NewLine;
	for (Int32 i = 0; ; i++) { 
        Int32 ptrToModel = 0;
		r.ReadMemoryInt32((IntPtr)(pFirstUnit + (0x04 * i)), ref ptrToModel);
		if (ptrToModel == 0)
			break;
		Int32 modelnr = 0, ptrToModelNameStr = 0;
        r.ReadMemoryInt32((IntPtr)(ptrToModel + 0x04), ref ptrToModelNameStr);
        r.ReadMemoryInt32((IntPtr)(ptrToModel + 0x10), ref modelnr);
		Int32 modelnamelen = 0;
        r.ReadMemoryInt32((IntPtr)(ptrToModelNameStr), ref modelnamelen);
		if (modelnamelen > 45)
			break;
        String name = String.Empty;
		if (modelnamelen <= 7) {
            r.ReadMemory((IntPtr)(ptrToModelNameStr + 0x08), ref name);
		} else {
            Int32 ptrToModelName = 0;
            r.ReadMemoryInt32((IntPtr)(ptrToModelNameStr + 0x08), ref ptrToModelName);
            r.ReadMemory((IntPtr)(ptrToModelName), ref name);
		}
        s += "\"" + name + "\", /*" + i.ToString() + " 0x" + i.ToString("X") + " */ " + Environment.NewLine;
	}
    s += "};";
    TextWriter tw = new StreamWriter("date.txt");
    tw.Write(s);
    tw.Close();
	return;
}

    }
}
